﻿// ServiceModel.Silverlight.Tests.Tests.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.html
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       Tests.cs
// Author:     HSS\gbanta
// Created:    08/12/2010
// Modified:   12/05/2010
// ----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using HSS.ServiceModel;
using Microsoft.Silverlight.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ServiceModel.Silverlight5.Tests
{
	#region InterfaceTests
	[TestClass]
	[Tag("Interface")]
	public class InterfaceTests : SilverlightTest
	{
		[Asynchronous]
		[TestMethod]
		[Description("Baseline test VirtualChannel<IService>.Invoke with an Action operation and NO call back.")]
		public void BaselineInvokeAction()
		{
			EnqueueCallback(() =>
			{
				VirtualChannel<ITestService>.Invoke(s => s.InvokeActionAsyncTest());
				this.TestComplete();
			});
		}

		[Asynchronous]
		[TestMethod]
		[Description("Baseline test VirtualChannel<IService>.Invoke with an Action operation and call back.")]
		public void BaselineInvokeActionWithCallback()
		{
			var testResult = false;

			EnqueueCallback(() =>
			{
				VirtualChannel<ITestService>.Invoke(s => s.InvokeActionAsyncTest(), (error) =>
				{
					testResult = (null == error);
					if (!testResult)
						this.HandleException(error);
					this.TestComplete();
				});
			});
		}

		[Asynchronous]
		[TestMethod]
		[Description("Baseline test VirtualChannel<IService>.Invoke<TState> with an Action operation, call back and State.")]
		public void BaselineInvokeActionWithCallbackAndState()
		{
			var testResult = false;
			var state = "InvokeActionAsyncTestState";

			EnqueueCallback(() =>
			{
				VirtualChannel<ITestService>.Invoke(s => s.InvokeActionAsyncTest(), state, (error, userState) =>
				{
					testResult = (null == error);
					if (!testResult)
						this.HandleException(error);
					if (testResult)
						testResult = state == userState;
					try
					{
						Assert.IsTrue(testResult);
					}
					catch (Exception ex)
					{
						this.HandleException(ex);
					}
					this.TestComplete();
				});
			});
		}

		[Asynchronous]
		[TestMethod]
		[Description("Baseline test VirtualChannel<IService>.Invoke<TResult> with an Func operation and call back.")]
		public void BaselineInvokeFunctionAsync()
		{
			var testResult = false;
			EnqueueCallback(() =>
			{
				VirtualChannel<ITestService>.Invoke(s => s.InvokeFuncAsyncTest(), (result, error) =>
				{
					testResult = (null == error);
					if (!testResult)
						this.HandleException(error);
					if (testResult)
						testResult = !string.IsNullOrEmpty(result);
					try
					{
						Assert.IsTrue(testResult);
					}
					catch (Exception ex)
					{
						this.HandleException(ex);
					}
					this.TestComplete();
				});
			});
		}

		[Asynchronous]
		[TestMethod]
		[Description("Baseline test VirtualChannel<IService>.Invoke<TResult,TState> with an Func operation, call back and State.")]
		public void BaselineInvokeFunctionAsyncWithState()
		{
			var testResult = false;
			var state = "InvokeFunctionAsyncWithState";

			EnqueueCallback(() =>
			{
				VirtualChannel<ITestService>.Invoke<string, string>(s => s.InvokeFuncAsyncTest(), state, (result, error, userState) =>
				{
					testResult = (null == error);
					if (!testResult)
						this.HandleException(error);
					if (testResult)
						testResult = !string.IsNullOrEmpty(result);
					if (testResult)
						testResult = state == userState;
					try
					{
						Assert.IsTrue(testResult);
					}
					catch (Exception ex)
					{
						this.HandleException(ex);
					}
					this.TestComplete();
				});
			});
		}

		[Asynchronous]
		[TestMethod]
		[Description("Ensures server side exceptions are provided back to the caller for handling.")]
		public void HandlesErrors()
		{
			EnqueueCallback(() =>
			{
				VirtualChannel<ITestService>.Invoke(s => s.InvokeActionWithErrorAsyncTest(), (error) =>
				{
					if (null == error)
						this.HandleException(new Exception("Expected to receive an error!"));
					this.TestComplete();
				});
			});
		}

		[Asynchronous]
		[TestMethod]
		[Description("Attempts to get a collection of DTO objects.")]
		public void CallGetAllPeople()
		{
			EnqueueCallback(() =>
			{
				VirtualChannel<ITestService>.Invoke(s => s.GetAllPeople(), (result, error) =>
				{
					if (null != error)
						this.HandleException(error);
					if (null == result)
						this.HandleException(new Exception("Failed to get all people."));
					if (result.Count() == 0)
						this.HandleException(new Exception("result count equal 0."));
					this.TestComplete();
				});
			});
		}

		[Asynchronous]
		[TestMethod]
		[Description("Attempts to Update a given DTO object.")]
		public void CallUpdatePerson()
		{
			EnqueueCallback(() =>
			{
				var p = new Person();
				p.FirstName = "Chuck";
				VirtualChannel<ITestService>.Invoke(s => s.UpdatePerson(p), (result, error) =>
				{
					if (null != error)
						this.HandleException(error);
					if (!result)
						this.HandleException(new Exception("Failed to update the provided person."));
					this.TestComplete();
				});
			});
		}

		[Asynchronous]
		[TestMethod]
		[Description("Attempts to add a collection of DTO objects.")]
		public void CallAddPeople()
		{
			EnqueueCallback(() =>
			{
				var people = new List<Person>();

				var p = new Person();
				p.FirstName = "Chucky";
				people.Add(p);

				p = new Person();
				p.FirstName = "The Bride of Chucky";
				people.Add(p);

				VirtualChannel<ITestService>.Invoke(s => s.AddPeople(people), (result, error) =>
				{
					if (null != error)
						this.HandleException(error);
					if (!result)
						this.HandleException(new Exception("Failed to update the provided person."));
					this.TestComplete();
				});

			});
		}

	}
	#endregion

	#region TimeoutTests
	[TestClass]
	[Tag("Timeout")]
	public class TimeoutTests : SilverlightTest
	{
		[Asynchronous]
		[TestMethod]
		[Description("Validates the service send timeout exception actually occurs.")]
		public void InvokeSendTimeoutShouldFail()
		{
			EnqueueCallback(() =>
			{
				// Default send timeout is 1 minute
				// Request the service to delay 1 minute and 1 second
				VirtualChannel<ITestService>.Invoke(s => s.InvokeTimeDelayed(61), (error) =>
				{
					if (null == error)
						this.HandleException(new Exception("Expected to receive an error!"));
					this.TestComplete();
				});
			});
		}

		[Asynchronous]
		[TestMethod]
		[Description("Validates the service send timeout exception does not occur.")]
		public void InvokeSendTimeoutShouldNotFail()
		{
			EnqueueCallback(() =>
			{
				// Default send timeout is 1 minute
				// Request the service to delay 59 second
				VirtualChannel<ITestService>.Invoke(s => s.InvokeTimeDelayed(59), (error) =>
				{
					if (null != error)
						this.HandleException(error);
					this.TestComplete();
				});
			});
		}

	}
	#endregion
}